﻿namespace Okazuki.MVVM.PrismSupport.Interactivity
{
    using System;
    using System.Threading;
    using System.Windows.Interactivity;
    using System.Windows.Threading;
    using Microsoft.Practices.Prism.Interactivity.InteractionRequest;

    /// <summary>
    /// Actionを必ずUIスレッド上で実行するアクション
    /// </summary>
    /// <typeparam name="T">ターゲットの型</typeparam>
    public abstract class DispatcherTargetTriggerAction<T> : TargetedTriggerAction<T>
        where T : class
    {
        private Dispatcher dispatcher;

        protected override void OnAttached()
        {
            base.OnAttached();
            this.dispatcher = this.AssociatedObject.Dispatcher;
        }

        protected override void OnDetaching()
        {
            this.dispatcher = null;
            base.OnDetaching();
        }

        protected sealed override void Invoke(object parameter)
        {
            var e = parameter as InteractionRequestedEventArgs ?? InteractionRequestEventArgsNullObject.Empty;
            if (this.dispatcher == null || this.dispatcher.CheckAccess())
            {
                this.InvokeAction(e);
            }
            else
            {
                this.dispatcher.BeginInvoke(
                    (Action<InteractionRequestedEventArgs>)this.InvokeAction,
                    e);
            }
        }

        protected abstract void InvokeAction(InteractionRequestedEventArgs e);
    }
}
